#include "Text.h"

#include "../Rect.h"
#include "../_Luly.h"
#include "_Color.h"
#include "_Font.h"
static SDL_Renderer* p_renderer;

void Text::str_lines_update() {
  str_lines.clear();
  str_lines.reserve(100);
  size_t last_pos = 0;
  maxLenPos = 0;
  size_t currentPos = 0;
  for (size_t pos = 0; pos < str.size(); pos++) {
    if (str[pos] == '\n') {
      str_lines.push_back(str.substr(last_pos, pos - last_pos));
      currentPos = str_lines.size() - 1;
      if (str.substr(last_pos, pos - last_pos).size() >
          str_lines[maxLenPos].size()) {
        maxLenPos = currentPos;
      }
      last_pos = pos + 1;
    } else if (pos == str.size() - 1) {
      if (str.substr(last_pos, pos - last_pos).size() >
          str_lines[maxLenPos].size()) {
        maxLenPos = currentPos + 1;
      }
      str_lines.push_back(str.substr(last_pos, pos + 1 - last_pos));
    }
  }
}

void Text::str_lines_update_byWH(int width, int height) {
  str_lines.clear();
  str_lines.reserve(100);
  size_t last_pos = 0;
  maxLenPos = 0;
  size_t currentPos = 0;
  for (size_t pos = 0; pos < str.size(); pos++) {
    if (str[pos] == '\n') {
      str_lines.push_back(str.substr(last_pos, pos - last_pos));
      currentPos = str_lines.size() - 1;
      if (str.substr(last_pos, pos - last_pos).size() >
          str_lines[maxLenPos].size()) {
        maxLenPos = currentPos;
      }
      last_pos = pos + 1;
    } else if (pos == str.size() - 1) {
      if (str.substr(last_pos, pos - last_pos).size() >
          str_lines[maxLenPos].size()) {
        maxLenPos = currentPos + 1;
      }
      str_lines.push_back(str.substr(last_pos, pos + 1 - last_pos));
    }
  }
}

Text::Text(std::string str, Font font) : str(str), font(font) {
  str_lines_update();
}

void Text::init() { p_renderer = _Luly::getInstance().p_renderer; }

void Text::draw(Font font, Color::RGBA color, int x, int y, double scale,
                double angle) {
  TTF_Font* p_font = _Font::getInstance().getSDLFont(font.getID());
  int w = 0;
  int h = 0;
  if (str_lines.size() != 0) {
    TTF_SizeUTF8(p_font, str_lines[maxLenPos].c_str(), &w,
                 &h);  //取最长那行字符的宽高
    width = w;
    height = h * str_lines.size();
  }

  int deltaLineY = 0;
  for (size_t i = 0; i < str_lines.size(); i++) {
    drawInOneLine(font, color, str_lines[i], x, y + deltaLineY, scale, angle);
    deltaLineY += h;
  }
}

void Text::drawInOneLine(Font font, Color::RGBA color, std::string oneLineStr,
                         int x, int y, double scale, double angle) {
  TTF_Font* p_font = _Font::getInstance().getSDLFont(font.getID());
  SDL_Surface* p_surface =
      TTF_RenderUTF8_Solid(p_font, oneLineStr.c_str(), toSDLColor(color));
  SDL_Texture* p_texture = SDL_CreateTextureFromSurface(p_renderer, p_surface);

  int w = 0, h = 0;
  TTF_SizeUTF8(p_font, oneLineStr.c_str(), &w, &h);

  SDL_Rect src = {0, 0, w, h};
  SDL_FRect dest = {float(x), float(y), float(w * scale), float(h * scale)};
  SDL_FPoint point = {0, 0};
  SDL_RenderCopyExF(p_renderer, p_texture, &src, &dest, angle, &point,
                    SDL_FLIP_NONE);

  SDL_FreeSurface(p_surface);
  SDL_DestroyTexture(p_texture);
}

void Text::drawAreaInOneLine(Rect area, Font font, Color::RGBA color,
                             std::string oneLineStr, int x, int y, double scale,
                             double angle) {
  TTF_Font* p_font = _Font::getInstance().getSDLFont(font.getID());
  SDL_Surface* p_surface =
      TTF_RenderUTF8_Solid(p_font, oneLineStr.c_str(), toSDLColor(color));
  SDL_Texture* p_texture = SDL_CreateTextureFromSurface(p_renderer, p_surface);

  int w = 0, h = 0;
  TTF_SizeUTF8(p_font, oneLineStr.c_str(), &w, &h);
  int srcx = area.x - x;
  srcx = (srcx < 0) ? 0 : srcx;
  int srcy = area.y - y;
  srcy = (srcy < 0) ? 0 : srcy;
  int srcw = overlap(area.x, area.x + area.width, x, x + w);
  // printf("%d\n", srcw);
  int srch = overlap(area.y, area.y + area.height, y, y + h);
  SDL_Rect src = {srcx, srcy, srcw, srch};
  // SDL_Rect src = {0,0,w,h};
  SDL_FRect dest = {float(x + srcx), float(y + srcy), float(srcw * scale),
                    float(srch * scale)};
  SDL_FPoint point = {0, 0};
  SDL_RenderCopyExF(p_renderer, p_texture, &src, &dest, angle, &point,
                    SDL_FLIP_NONE);

  SDL_FreeSurface(p_surface);
  SDL_DestroyTexture(p_texture);
  // drawArea(Rect{x, y, width, height}, font, color, x, y, scale, angle);
}
void Text::drawArea(Rect area, Font font, Color::RGBA color, int x, int y,
                    double scale, double angle) {
  TTF_Font* p_font = _Font::getInstance().getSDLFont(font.getID());
  int w = 0;
  int h = 0;
  if (str_lines.size() != 0) {
    TTF_SizeUTF8(p_font, str_lines[maxLenPos].c_str(), &w,
                 &h);  //取最长那行字符的宽高
    width = w;
    height = h * str_lines.size();
    // SDL_LogError(0, "%s,1w:%d,h:%d\n",str_lines[maxLenPos].c_str(), w, h);
  }

  int deltaLineY = 0;
  for (size_t i = 0; i < str_lines.size(); i++) {
    // drawAreaInOneLine(area, font, color, str_lines[i], x, y + deltaLineY,
    // scale,
    //                   angle);
    int w = 0, h = 0;
    TTF_SizeUTF8(p_font, str_lines[i].c_str(), &w, &h);
    // SDL_LogError(0, "%s,2w:%d,h:%d\n",str_lines[i].c_str(), w, h);
    drawAreaInOneLine1(area, Rect{0, 0, w, h},
                       Rect{x, y + deltaLineY, int(w * scale), int(h * scale)},
                       font, str_lines[i], color, angle);
    deltaLineY += h;
  }
  // SDL_LogError(0, "%d,3w:%d,h:%d\n",maxLenPos, w, h);
}

void Text::drawAreaInOneLine1(Rect area, Rect cut, Rect dest, Font font,
                              std::string oneLineStr, Color::RGBA color,
                              double angle) {
  TTF_Font* p_font = _Font::getInstance().getSDLFont(font.getID());
  SDL_Surface* p_surface =
      TTF_RenderUTF8_Solid(p_font, oneLineStr.c_str(), toSDLColor(color));
  SDL_Texture* p_texture = SDL_CreateTextureFromSurface(p_renderer, p_surface);

  int relativeX = area.x - dest.x;
  relativeX = (relativeX < 0) ? 0 : relativeX;
  int relativeY = area.y - dest.y;
  relativeY = (relativeY < 0) ? 0 : relativeY;
  int destw = overlap(dest.x, dest.x + dest.width, area.x, area.x + area.width);
  int desth =
      overlap(dest.y, dest.y + dest.height, area.y, area.y + area.height);
  int srcx = (int)((relativeX / (float)dest.width) * cut.width);
  int srcy = (int)((relativeY / (float)dest.height) * cut.height);
  int srcw = (int)((destw / (float)dest.width) * cut.width);
  int srch = (int)((desth / (float)dest.height) * cut.height);
  SDL_Rect src = {cut.x + srcx, cut.y + srcy, srcw, srch};

  SDL_FRect sdldest = {float(dest.x + relativeX), float(dest.y + relativeY),
                       float(destw), float(desth)};
  // image.draw(imageId, src, dest.x + relativeX, dest.y + relativeY, destw,
  // desth,
  //            angle);
  SDL_FPoint point = {0, 0};
  SDL_RenderCopyExF(p_renderer, p_texture, &src, &sdldest, angle, &point,
                    SDL_FLIP_NONE);
  SDL_FreeSurface(p_surface);
  SDL_DestroyTexture(p_texture);
}